/**
 * 
 */
package kr.or.smardi.smardi_AScan.Graph;

import java.text.*;
import java.util.*;

import kr.or.smardi.smardi_AScan.Device.*;
import android.content.*;
import android.graphics.*;
import android.graphics.Paint.Align;
import android.graphics.Paint.FontMetrics;
import android.graphics.Paint.Join;
import android.graphics.drawable.*;
import android.util.*;
import android.view.*;

/**
 * @author Wenly
 * 
 */

public class Graph {
	boolean D = false;
	private final String TAG = "floroGraph";

	DisplayMetrics outMetrics = new DisplayMetrics();
	Window window;
	public Origin origin;
	public Size size;
	Context context;

	final float DEFAULT_ORI_X = 0; // 기본 원점 위치
	final float DEFAULT_ORI_Y = 50;

	final float DEFAULT_WIDTH = 600; // 기본 사이즈
	final float DEFAULT_HEIGHT = 300;

	int colorLine = 0; // 그래프 색
	int colorPoint = 0;

	AxisX axisX; // 축 관련된 변수 선언
	AxisY axisY;

	// 그래프 데이터들의 바운더리
	long dataBoundary_right = 0;
	long dataBoundary_left = 0;
	double dataBoundary_top = 0;
	double dataBoundary_bottom = 0;

	// Margin of top of graph
	int graphMarginTop = DPtoPX(10);

	ArrayList<ArrayList<GraphData>> arrayGraphData = new ArrayList<ArrayList<GraphData>>();
	ArrayList<Integer> arrayGraphColor = new ArrayList<Integer>();
	ArrayList<String> arrayGraphTitle = new ArrayList<String>();

	public int unitType = 0; // 단위를 나타내는

	private ArrayList<LookupTable.dataSet> lookupTable = null;

	// 그래프의 현재 상태를 나타내기 위한 변수
	public int state_ascan = 0;
	public static final int STATE_ASCAN_PREHEATING = 0;
	public static final int STATE_ASCAN_SCANNING = 1;
	public static final int STATE_ASCAN_DETECTING = 2;
	public static final int STATE_ASCAN_END = 3;
	public static final int STATE_ASCAN_ERROR = 4;

	// Ready to blow 이미지
	public Drawable drawable_readyToBlow = null;

	public Graph(Window window) {
		this.window = window;
		window.getWindowManager().getDefaultDisplay().getMetrics(outMetrics);

		origin = new Origin(DEFAULT_ORI_X, DEFAULT_ORI_Y);
		size = new Size(DEFAULT_WIDTH, DEFAULT_HEIGHT);

		arrayGraphData = new ArrayList<ArrayList<GraphData>>();
		arrayGraphColor = new ArrayList<Integer>();
	}

	/**
	 * @param window
	 *            window
	 * @param width
	 *            그래프의 가로 길이
	 * @param height
	 *            그래프의 세로 길이
	 */
	public Graph(Window window, int width, int height) {
		this.window = window;
		window.getWindowManager().getDefaultDisplay().getMetrics(outMetrics);

		origin = new Origin(DEFAULT_ORI_X, DEFAULT_ORI_Y);
		size = new Size(width, height);

		arrayGraphData = new ArrayList<ArrayList<GraphData>>();
		arrayGraphColor = new ArrayList<Integer>();
	}

	public Graph(Window window, int ori_x, int ori_y, int width, int height,
			float minX, float maxX, float minY, float maxY) {
		this.window = window;
		window.getWindowManager().getDefaultDisplay().getMetrics(outMetrics);

		origin = new Origin(ori_x, ori_y);
		size = new Size(width, height);
		axisX = new AxisX();
		axisY = new AxisY();

		axisX.setMin(minX);
		axisX.setMax(maxX);
		axisY.setMin(minY);
		axisY.setMax(maxY);

		graphMarginTop = DPtoPX(10);
		arrayGraphData = new ArrayList<ArrayList<GraphData>>();
		arrayGraphColor = new ArrayList<Integer>();
	}

	/**
	 * @param window
	 *            window
	 * @param ori_x
	 *            원점의 x좌표
	 * @param ori_y
	 *            원점의 y좌표
	 * @param width
	 *            그래프의 가로 길이
	 * @param height
	 *            그래프의 세로 길이
	 */
	public Graph(Window window, int ori_x, int ori_y, int width, int height) {
		this.window = window;
		window.getWindowManager().getDefaultDisplay().getMetrics(outMetrics);

		origin = new Origin(ori_x, ori_y);
		size = new Size(width, height);
	}

	public Graph(int ori_x, int ori_y, int width, int height, float minX,
			float maxX, float minY, float maxY) {
		origin = new Origin(ori_x, ori_y);
		size = new Size(width, height);

		axisX = new AxisX();
		axisY = new AxisY();

		axisX.setMin(minX);
		axisX.setMax(maxX);
		axisY.setMin(minY);
		axisY.setMax(maxY);

		graphDatas = new ArrayList<GraphData>();
	}

	public class Origin {
		float x;
		float y;

		/**
		 * @param _x
		 *            unit: DP
		 * @param _y
		 *            unit: DP
		 */
		public Origin(float _x, float _y) {
			this.x = _x;
			this.y = _y;

			graphMarginTop = 10;
		}
	}

	public void setOrigin(float x, float y) {
		this.origin.x = x;
		this.origin.y = y;
	}

	public class Size {
		// 단위는 px
		float width;
		float height;

		/**
		 * @param _width
		 *            unit: DP
		 * @param _height
		 *            unit: DP
		 */
		public Size(float _width, float _height) {
			this.width = _width;
			this.height = _height;
		}
	}

	/**
	 * @author floro show: boolean labelBoxBorderColor: color position: "ne" or
	 *         "nw" or "se" or "sw" margin: number of pixels or [x margin, y
	 *         margin] backgroundColor: null or color
	 */
	public class Legend {
		private boolean show;
		private int labelBoxBorderColor;
		private String position;
		private int margin;
		private int backgroundColor;

		public Legend() {
			setShow(false);
			setLabelBoxBorderColor(Color.GRAY);
			setPosition("nw");
			setMargin(10);
			setBackgroundColor(Color.argb(125, 255, 255, 255));
		}

		void setShow(boolean show) {
			this.show = show;
		}

		boolean isShow() {
			return show;
		}

		void setLabelBoxBorderColor(int labelBoxBorderColor) {
			this.labelBoxBorderColor = labelBoxBorderColor;
		}

		int getLabelBoxBorderColor() {
			return labelBoxBorderColor;
		}

		void setPosition(String position) {
			this.position = position;
		}

		String getPosition() {
			return position;
		}

		void setMargin(int margin) {
			this.margin = margin;
		}

		int getMargin() {
			return margin;
		}

		void setBackgroundColor(int backgroundColor) {
			this.backgroundColor = backgroundColor;
		}

		int getBackgroundColor() {
			return backgroundColor;
		}

	}

	/**
	 * @author floro mode: null or "time" min: Float.NEGATIVE_INFINITY or number
	 *         max: Float.POSITIVE_INFINITY or number autoscaleMargin: null or
	 *         number
	 * 
	 *         ticks: null or number or ticks array or (fn: range -> ticks
	 *         array) tickSize: number or array
	 */
	public class AxisX {
		private String mode;
		private float min;
		private float max;
		private int autoscaleMargin;

		private ArrayList<Ticks> ticks;
		private int tickSize;

		public AxisX() {
			this.setMode(null);
			this.setMin(Float.NEGATIVE_INFINITY);
			this.setMax(Float.POSITIVE_INFINITY);
			this.setAutoscaleMargin(10);
			this.setTicks(null);
			this.setTickSize(0);
		}

		public String getMode() {
			return mode;
		}

		public void setMode(String mode) {
			this.mode = mode;
		}

		public float getMin() {
			return min;
		}

		public void setMin(float min) {
			this.min = min;
		}

		public float getMax() {
			return max;
		}

		public void setMax(float max) {
			this.max = max;
		}

		public int getAutoscaleMargin() {
			return autoscaleMargin;
		}

		/**
		 * @param autoscaleMargin
		 *            DP 단위로 넣을 것
		 */
		public void setAutoscaleMargin(int autoscaleMargin) {
			this.autoscaleMargin = autoscaleMargin;
		}

		public ArrayList<Ticks> getTicks() {
			return ticks;
		}

		public void setTicks(ArrayList<Ticks> ticks) {
			this.ticks = ticks;
		}

		public int getTickSize() {
			return tickSize;
		}

		public void setTickSize(int tickSize) {
			this.tickSize = tickSize;
		}
	}

	/**
	 * @author floro mode: null or "time" min: Float.NEGATIVE_INFINITY or number
	 *         max: Float.POSITIVE_INFINITY or number autoscaleMargin: null or
	 *         number
	 * 
	 *         ticks: null or number or ticks array or (fn: range -> ticks
	 *         array) tickSize: number or array
	 */
	public class AxisY {
		private String mode;
		private float min;
		private float max;
		private int autoscaleMargin;

		private ArrayList<Ticks> ticks;
		private int tickSize;

		public AxisY() {
			this.setMode(null);
			this.setMin(Float.NEGATIVE_INFINITY);
			this.setMax(Float.POSITIVE_INFINITY);
			this.setAutoscaleMargin(10);
			this.setTicks(null);
			this.setTickSize(0);
		}

		public String getMode() {
			return mode;
		}

		public void setMode(String mode) {
			this.mode = mode;
		}

		public float getMin() {
			return min;
		}

		public void setMin(float min) {
			this.min = min;
		}

		public float getMax() {
			return max;
		}

		public void setMax(float max) {
			this.max = max;
		}

		public int getAutoscaleMargin() {
			return autoscaleMargin;
		}

		public void setAutoscaleMargin(int autoscaleMargin) {
			this.autoscaleMargin = autoscaleMargin;
		}

		public ArrayList<Ticks> getTicks() {
			return ticks;
		}

		public void setTicks(ArrayList<Ticks> ticks) {
			this.ticks = ticks;
		}

		public int getTickSize() {
			return tickSize;
		}

		public void setTickSize(int tickSize) {
			this.tickSize = tickSize;
		}
	}

	public class Ticks {
		float XorY;
		String value;

		public Ticks(float _XorY, String _value) {
			this.XorY = _XorY;
			this.value = _value;
		}
	}

	/**
	 * @param width
	 *            unit: DP
	 * @param height
	 *            unit: DP
	 */
	public void setSize(float width, float height) {
		this.size.width = width;
		this.size.height = height;
	}

	// GraphData graphDatas[] = new GraphData[10];
	ArrayList<GraphData> graphDatas = new ArrayList<GraphData>();
	// ArrayList<Graphdata> graphDatas = new ArrayList()<Graphdata>;

	int dataCount = 0;

	public void addData(GraphData data) {
		graphDatas.add(data);
	}

	public void addData(long x, float y) {
		GraphData data = new GraphData(x, y);
		graphDatas.add(data);
	}

	public void removeDataAtIndex(int index) {
		if (index < graphDatas.size()) {
			graphDatas.remove(index);
		}
	}

	public void addDataArray(ArrayList<GraphData> _graphDatas, int color,
			String title) {
		arrayGraphData.add(_graphDatas);
		arrayGraphColor.add(color);
		arrayGraphTitle.add(title);
	}

	public void removeAllData() {
		graphDatas = new ArrayList<GraphData>();
	}

	public int DPtoPX(float dp) {
		return Math.round(outMetrics.density * dp);
	}

	// 룩업테이블을 설정한다 A-Scan 전용
	public void setLookupTable(ArrayList<LookupTable.dataSet> table) {
		lookupTable = table;
	}

	/**
	 * @param canvas
	 *            canvas
	 * @param showLine
	 *            라인을 나타낼지 여부
	 * @param showPoint
	 *            지점을 나타낼지 여부
	 */
	public void makeGraph(Canvas canvas, boolean showLine, boolean showPoint) {
		Paint paint = new Paint();

		long minX = 0;
		double minY = 0;
		long maxX = 0;
		double maxY = 0;

		if (dataBoundary_left > 0) {
			minX = dataBoundary_left;
		}

		// 마지막 값이 최대의 x값
		if (graphDatas.size() > 0) {
			maxX = graphDatas.get(graphDatas.size() - 1).x;
			maxY = graphDatas.get(graphDatas.size() - 1).y;
		}

		// 만약 데이터의 최대 x값이 지정된 값보다 작으면
		// 지정된 값을 최대값으로 지정
		// 이렇게 하면
		// 데이터가 valueofRightBoundary 보다 작을 때에는 축이 고정된 채로 그래프가 그려지고
		// valueofRightBoundary보다 클 때는 축 자체가 축소되면서 그려짐
		if (maxX <= dataBoundary_left
				+ (dataBoundary_right - dataBoundary_left) * 2 / 2) {
			maxX = dataBoundary_right;
		} else {
			// dataBoundary_right = (long) (minX + (maxX - minX) * 1.15);
			dataBoundary_right = (long) ((long) dataBoundary_left + (dataBoundary_right - dataBoundary_left) * 1.15);
			return;
		}

		// 룩업 테이블의 최대값 110%를 최대로 설정한다.
		if (maxY <= dataBoundary_top) {
			maxY = dataBoundary_top;
		} else {
			// Log.e(TAG, "maxY:" + maxY + " top:" + dataBoundary_top);
			dataBoundary_top = (double) (minY + (maxY - minY) * 1.15);
			return;
		}

		if (D) {
			Log.v(TAG, "------------------------------");
			Log.e(TAG, "graphDatas.size():" + graphDatas.size());
			Log.v(TAG, "Input data boundary is");
			Log.v(TAG, "minX:" + minX);
			Log.v(TAG, "maxX:" + maxX);
			Log.v(TAG, "minY:" + minY);
			Log.v(TAG, "maxY:" + maxY);
			Log.v(TAG, "------------------------------");
		}

		// 그래프 그려질 범위를 그림========================
		paint.setAntiAlias(true);
		paint.setColor(Color.rgb(88, 89, 91));
		paint.setStyle(Paint.Style.STROKE);
		paint.setStrokeWidth(1);

		if (D) {
			Log.v(TAG, "------------------------------");
			Log.v(TAG, "Graph Size is");
			Log.v(TAG, "size(w):" + size.width);
			Log.v(TAG, "size(h):" + size.height);
			Log.v(TAG, "Origin of graph is");
			Log.v(TAG, "origin(x):" + origin.x);
			Log.v(TAG, "origin(y):" + origin.y);
			Log.v(TAG, "------------------------------");
		}

		// canvas.drawLine(origin.px_x, graphMarginTop, size.px_width,
		// graphMarginTop, paint);
		canvas.drawLine(origin.x, size.height - origin.y + graphMarginTop,
				size.width, size.height - origin.y + graphMarginTop, paint);
		// canvas.drawRect(origin.px_x, graphMarginTop, size.px_width,
		// size.px_height - origin.px_y + graphMarginTop, paint);

		if (D) {
			Log.v(TAG, "------------------------------");
			Log.v(TAG, "Axis Size is");
			Log.v(TAG, "X axis min:" + axisX.getMin());
			Log.v(TAG, "X axis max:" + axisX.getMax());
			Log.v(TAG, "Y axis min:" + axisY.getMin());
			Log.v(TAG, "Y axis max:" + axisY.getMax());
			Log.v(TAG, "------------------------------");
		}

		double dataRangeWidth_graph = (size.width - origin.x) - 2
				* axisX.getAutoscaleMargin();
		double dataRangeWidth_data = maxX - minX;
		float dataRangeHeight_graph = (size.height - origin.y) - 2
				* axisY.getAutoscaleMargin();
		double dataRangeHeight_data = maxY - minY;
		double scaleX = dataRangeWidth_graph / dataRangeWidth_data;
		double scaleY = dataRangeHeight_graph / dataRangeHeight_data;

		float offsetDataX = axisX.getAutoscaleMargin();
		float offsetDataY = axisY.getAutoscaleMargin();

		paint.setStrokeWidth(1);
		paint.setColor(Color.GRAY);

		// 룩업테이블 범위를 그림========================
		if (lookupTable != null) {
			makeLookupTable(minX, minY, scaleX, scaleY, offsetDataX,
					offsetDataY, canvas);
		}

		// 예열 상태 범위를 그림========================
		makePreheating(minX, minY, scaleX, scaleY, offsetDataX, offsetDataY,
				canvas);

		// 라인을 그린다.
		makeLineAtGraph(minX, minY, scaleX, scaleY, offsetDataX, offsetDataY,
				canvas);
	}

	private void makePreheating(long minX, double minY, double scaleX,
			double scaleY, float offsetDataX, float offsetDataY, Canvas canvas) {
		Paint paint = new Paint();
		paint.setAntiAlias(true);

		int left = (int) origin.x;
		int right = (int) size.width;
		int height = (int) ((size.height - origin.y)
				- Math.round((0.0075 - minY) * scaleY + offsetDataY) + graphMarginTop);

		paint.setColor(Color.WHITE);
		paint.setShadowLayer(4, 0, 3, Color.GRAY);
		paint.setStrokeWidth(8);
		DashPathEffect dathPath = new DashPathEffect(new float[] { 20, 7 }, 1);
		paint.setPathEffect(dathPath);

		canvas.drawLine(left, height, right, height, paint);
	}

	private void makeLookupTable(long minX, double minY, double scaleX,
			double scaleY, float offsetDataX, float offsetDataY, Canvas canvas) {
		Paint paint = new Paint();
		paint.setAntiAlias(true);

		int left = (int) origin.x;
		int right = (int) size.width;

		/*
		 * // 오른쪽 그라디언트 사각형 생성 Paint rightPaint = new Paint();
		 * rightPaint.setShader(new LinearGradient(right, 0, right -
		 * (right-left)/9, 0, Color.rgb(0x8B, 0x8B, 0x8B), Color.WHITE,
		 * Shader.TileMode.CLAMP)); canvas.drawPaint(rightPaint);
		 */

		// Ready to blow를 표시한다.
		if (state_ascan == STATE_ASCAN_PREHEATING) {
			Paint readyPaint = new Paint();
			readyPaint.setAntiAlias(true);
			readyPaint.setFilterBitmap(true);
			readyPaint.setDither(true);

			BitmapDrawable mBmDrawable = (BitmapDrawable) drawable_readyToBlow;
			Bitmap bitmap = mBmDrawable.getBitmap();
			Matrix matrix = new Matrix();

			float imageSpace = (int) (Math.round((0.006 - minY) * scaleY
					+ offsetDataY) - Math.round((0.001 - minY) * scaleY
					+ offsetDataY));
			float scale_x = (float) (imageSpace / (float) bitmap.getHeight());
			matrix.postScale(scale_x, scale_x);

			try {
				bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
						bitmap.getHeight(), matrix, false);
				canvas.drawBitmap(
						bitmap,
						(right - left) / 15,
						(int) ((size.height - origin.y)
								- Math.round((0.006 - minY) * scaleY
										+ offsetDataY) + graphMarginTop),
						readyPaint);
			}catch(Exception e) {
				Log.e(TAG, "Error in \"Ready to blow\":"+e.getLocalizedMessage());
			}
		}
		/*
		 * mBmDrawable.setBounds(left, 100, mBmDrawable.getBounds().right,
		 * mBmDrawable.getBounds().bottom); mBmDrawable.draw(canvas);
		 */

		// 보조선을 그린다.
		float startSubLine = 0f;
		float intervalSubLine = 0f;
		if (dataBoundary_top <= 0.1) {
			startSubLine = 0.008f;
			intervalSubLine = 0.002f;
		} else {
			startSubLine = 0.01f;
			intervalSubLine = 0.01f;
		}

		Paint dashSubLine = new Paint();
		for (float i = startSubLine; i <= dataBoundary_top; i = i
				+ intervalSubLine) {
			dashSubLine.setColor(Color.rgb(0xD9, 0xD9, 0xD9));
			DashPathEffect dashPath = new DashPathEffect(new float[] { 2, 2 },
					1);
			dashSubLine.setPathEffect(dashPath);
			dashSubLine.setStrokeWidth(2);

			float subHight = (int) ((size.height - origin.y)
					- Math.round((i - minY) * scaleY + offsetDataY) + graphMarginTop);
			;
			canvas.drawLine(left, subHight, right, subHight, dashSubLine);
		}
		// dashSubLine = null;

		// 왼쪽 테두리를 그린다.
		canvas.drawLine(left, 0, left, size.height - origin.y + graphMarginTop,
				dashSubLine);

		// 아래쪽 테두리를 그린다.
		Paint bottomPaint = new Paint();
		bottomPaint.setStrokeWidth(3);
		bottomPaint.setColor(Color.rgb(0xBF, 0xBF, 0xBF));
		canvas.drawLine(left, size.height - origin.y, right, size.height
				- origin.y, bottomPaint);

		// 위쪽 테두리를 그린다.
		canvas.drawLine(left, 0, right, 0, bottomPaint);

		// 굵은 주선을 그린다.
		for (int i = 0; i < lookupTable.size() - 1; i++) {
			if (lookupTable.get(i).y < dataBoundary_top) {

				float textSize = 0;

				if (dataBoundary_top >= 0.07) {

					int a = (int) (lookupTable.get(i + 1).y * 100);

					if ((int) (lookupTable.get(i + 1).y * 100) % 2 == 0
							&& lookupTable.get(i + 1).y < 0.1) {
						// 짝수는 스킵(0.02 0.04 0.06)
						continue;
					}
					textSize = (float) (size.height / 8.);
				} else {
					textSize = (float) (size.height / 10.);
				}

				if (dataBoundary_top >= 0.1) {
					if (lookupTable.get(i + 1).y != 0.05
							&& lookupTable.get(i + 1).y < 0.1) {
						continue;
					}
					textSize = (float) (size.height / 7.);
				}

				if (dataBoundary_top >= 0.2) {
					if (lookupTable.get(i + 1).y < 0.1) {
						// continue;
					}
					textSize = (float) (size.height / 7.);
				}

				if (dataBoundary_top >= 0.25) {
					textSize = (float) (size.height / 9.);
				}

				int bottom = (int) ((size.height - origin.y)
						- Math.round((lookupTable.get(i).y - minY) * scaleY
								+ offsetDataY) + graphMarginTop);
				int top = (int) ((size.height - origin.y)
						- Math.round((lookupTable.get(i + 1).y - minY) * scaleY
								+ offsetDataY) + graphMarginTop);

				// 각 지표마다 굵은 선을 표시한다.
				paint.setColor(Color.rgb(0xDB, 0xDB, 0xDB));
				paint.setStrokeWidth(6);
				paint.setStrokeJoin(Join.ROUND);
				canvas.drawLine(left, top, right, top, paint);

				// 각 지표의 왼쪽 끝에 동그라미를 그린다.
				paint.setColor(Color.rgb(0xC0, 0x00, 0x00));
				float outerRadius = 14;
				canvas.drawCircle(left + outerRadius, top, outerRadius, paint);
				float InnerRadius = outerRadius - 4;
				paint.setColor(Color.WHITE);
				canvas.drawCircle(left + outerRadius, top, InnerRadius, paint);

				// 각 지표에 해당하는 숫자를 적는다.
				paint.setColor(Color.rgb(0xD9, 0xD9, 0xD9));
				// float textsize = (float) ((bottom-top)/4.);

				paint.setTextSize(textSize);
				canvas.drawText(lookupTable.get(i + 1).y + "%",
						(float) ((right - left) * 0.175), top - 10, paint);
			}
		}
	}

	private void makeLineAtGraph(double minX, double minY, double scaleX,
			double scaleY, float offsetDataX, float offsetDataY, Canvas canvas) {
		Paint paint = new Paint();
		paint.setStrokeWidth(6);
		paint.setAntiAlias(true);
		paint.setColor(Color.rgb(190, 75, 72));

		if (D) {
			Log.e(TAG, "scale X:" + scaleX);
			Log.e(TAG, "scale Y:" + scaleY);
		}

		int countSkip = 0;

		for (int i = 0; i < graphDatas.size() - 1; i++) {
			if (i < graphDatas.size() - 300) {
				if (i % 2 == 0) {
					// 오래된 데이터는 2중 하나를 스킵한다.
					countSkip++;
					continue;
				}
			}
			if (i < graphDatas.size() - 600) {
				if (i % 3 == 0) {
					// 더 오래된 데이터는 3 중 하나를 스킵한다.
					countSkip++;
					continue;
				}
			}
			if (i < graphDatas.size() - 1200) {
				if (i % 5 == 0) {
					// 더더 오래된 데이터는 5 중 하나를 스킵한다.
					countSkip++;
					continue;
				}
			}

			int pointX = (int) Math
					.round((graphDatas.get(i - countSkip).x - minX) * scaleX
							+ offsetDataX);
			int pointX2 = (int) Math.round((graphDatas.get(i + 1).x - minX)
					* scaleX + offsetDataX);
			int pointY = (int) ((size.height - origin.y)
					- Math.round((graphDatas.get(i - countSkip).y - minY)
							* scaleY + offsetDataY) + graphMarginTop);
			int pointY2 = (int) ((size.height - origin.y)
					- Math.round((graphDatas.get(i + 1).y - minY) * scaleY
							+ offsetDataY) + graphMarginTop);

			/*
			 * if(D) { Log.e(TAG, "px_X:"+pointX+ " x:" + graphDatas.get(i).x);
			 * Log.e(TAG, "px_Y:"+pointY+ " y:" + graphDatas.get(i).y); }
			 */
			canvas.drawLine(origin.x + pointX, pointY, origin.x + pointX2,
					pointY2, paint);

			countSkip = 0;
			/*
			 * 막대그래프 그릴 때 int pointX = Math.round((graphDatas.get(i).x - minX) *
			 * scaleX + offsetDataX); int pointY = (int) ((size.height -
			 * origin.y) - Math.round((graphDatas.get(i).y - minY) * scaleY +
			 * offsetDataY) + graphMarginTop);
			 * 
			 * canvas.drawLine(origin.x + pointX, pointY, origin.x + pointX,
			 * size.height - origin.y + graphMarginTop, paint);
			 */
		}
	}

	/**
	 * 포인트 상단에 해당 점수를 표시한다.
	 * 
	 * @param minX
	 * @param minY
	 * @param scaleX
	 * @param scaleY
	 * @param offsetDataX
	 * @param offsetDataY
	 * @param canvas
	 * @param color
	 */
	@SuppressWarnings("unused")
	private void makeNumberAtPoint(float minX, float minY, float scaleX,
			float scaleY, float offsetDataX, float offsetDataY, Canvas canvas,
			int color) {
		Paint paint = new Paint();
		paint.setAntiAlias(true);

		for (int i = 0; i < graphDatas.size(); i++) {
			if (color == 0) {
				paint.setColor(Color.rgb(88, 89, 91));
			} else {
				paint.setColor(color);
			}

			int pointX = Math.round((graphDatas.get(i).x - minX) * scaleX
					+ offsetDataX);
			int pointY = (int) ((size.height - origin.y)
					- Math.round((graphDatas.get(i).y - minY) * scaleY
							+ offsetDataY) + graphMarginTop);

			canvas.drawCircle(origin.x + pointX, pointY, 5, paint);
			paint.setColor(Color.WHITE);
			canvas.drawCircle(origin.x + pointX, pointY, 3, paint);
		}
	}

	@SuppressWarnings("unused")
	private void makePointAtGraph(float minX, float minY, float scaleX,
			float scaleY, float offsetDataX, float offsetDataY, Canvas canvas,
			int color) {
		Paint paint = new Paint();
		paint.setAntiAlias(true);

		for (int i = 0; i < graphDatas.size(); i++) {
			if (color == 0) {
				paint.setColor(Color.rgb(71, 187, 255));
			} else {
				paint.setColor(color);
			}
			paint.setTextSize(16);

			int pointX = Math.round((graphDatas.get(i).x - minX) * scaleX
					+ offsetDataX);

			int pointY = (int) (size.height - origin.y) + 30;

			FontMetrics fontMetrics = paint.getFontMetrics();

			SimpleDateFormat sFormat = null;

			if (unitType == MyView.UNIT_DAY) {
				sFormat = new SimpleDateFormat("MM/dd");
			} else {
				sFormat = new SimpleDateFormat("HH:mm");
			}

			String text = sFormat.format(new Date((long) graphDatas.get(i).x));
			float textWidth = paint.measureText(text);

			if (i == 0) {
				// 왼쪽정렬
				canvas.drawText(text, origin.x + pointX, pointY
						- (fontMetrics.ascent + fontMetrics.descent) / 2, paint);
			} else if (i == graphDatas.size() - 1) {
				// 오른쪽 정렬
				canvas.drawText(text, origin.x + pointX - textWidth, pointY
						- (fontMetrics.ascent + fontMetrics.descent) / 2, paint);
			} else {
				// 가운데 정렬
				canvas.drawText(text, origin.x + pointX - textWidth / 2, pointY
						- (fontMetrics.ascent + fontMetrics.descent) / 2, paint);
			}

			/*
			 * canvas.drawCircle(origin.px_x + pointX, pointY, 8, paint);
			 * paint.setColor(Color.WHITE); canvas.drawCircle(origin.px_x +
			 * pointX, pointY, 5, paint);
			 */
		}
	}

	/**
	 * X축에 데이터의 인덱스를 표기한다. (월간일 경우 1, 2, 3, 4, 5) (일간일 경우 00:00, 00:10, 00:20,
	 * 00:30)
	 * 
	 * @param minX
	 * @param minY
	 * @param scaleX
	 * @param scaleY
	 * @param offsetDataX
	 * @param offsetDataY
	 * @param canvas
	 * @param color
	 */
	@SuppressWarnings("unused")
	private void makeIndexAtGraph(float minX, float minY, float scaleX,
			float scaleY, float offsetDataX, float offsetDataY, Canvas canvas,
			int color) {
		Paint paint = new Paint();
		paint.setAntiAlias(true);

		for (int i = 0; i < graphDatas.size(); i++) {
			if (color == 0) {
				paint.setColor(Color.rgb(71, 187, 255));
			} else {
				paint.setColor(color);
			}

			int pointX = Math.round((graphDatas.get(i).x - minX) * scaleX
					+ offsetDataX);
			int pointY = (int) ((size.height - origin.y)
					- Math.round((graphDatas.get(i).y - minY) * scaleY
							+ offsetDataY) + graphMarginTop - 20);

			FontMetrics fontMetrics = paint.getFontMetrics();

			String text = "" + Math.round(graphDatas.get(i).y);
			float textWidth = paint.measureText(text);

			canvas.drawText(text, origin.x + pointX - textWidth / 2, pointY
					- (fontMetrics.ascent + fontMetrics.descent) / 2, paint);
			/*
			 * canvas.drawCircle(origin.px_x + pointX, pointY, 8, paint);
			 * paint.setColor(Color.WHITE); canvas.drawCircle(origin.px_x +
			 * pointX, pointY, 5, paint);
			 */
		}
	}

	@SuppressWarnings("unused")
	private void makeAxixX(int space, float minX, float scaleX, Canvas canvas) {
		int spaceX = space;
		Paint paint = new Paint();
		paint.setColor(Color.GRAY);
		paint.setStrokeWidth(1);

		for (int i = 0; i * spaceX <= size.width - origin.x; i++) {
			if (i % 5 == 0) {
				canvas.drawLine(origin.x + i * spaceX, size.height - origin.y
						+ graphMarginTop, origin.x + i * spaceX, size.height
						- origin.y + 10 + graphMarginTop, paint);
				paint.setTextAlign(Align.CENTER);
				paint.setAntiAlias(true);
				canvas.drawText(
						String.format(
								"%.1f",
								minX
										+ ((i * spaceX - axisX
												.getAutoscaleMargin()) / scaleX)),
						origin.x + i * spaceX, size.height - origin.y + 25
								+ graphMarginTop, paint);
				paint.setAntiAlias(false);
				continue;
			}

			canvas.drawLine(origin.x + i * spaceX, size.height - origin.y
					+ graphMarginTop, origin.x + i * spaceX, size.height
					- origin.y + 5 + graphMarginTop, paint);
		}
	}

	@SuppressWarnings("unused")
	private void makeAxixY(int space, float minY, float scaleY, Canvas canvas,
			boolean Grid) {
		int spaceY = space;
		Paint paint = new Paint();
		paint.setColor(Color.GRAY);
		paint.setStrokeWidth(1);

		for (int i = 0; i * spaceY <= size.height - origin.y; i++) {
			paint.setAlpha(200);
			if (i % 5 == 0) {
				canvas.drawLine(origin.x, size.height - origin.y - spaceY * i
						+ graphMarginTop, origin.x + -10, size.height
						- origin.y - spaceY * i + graphMarginTop, paint);
				if (Grid == true) {
					// 그리드를 그린다.
					canvas.drawLine(origin.x, size.height - origin.y - spaceY
							* i + graphMarginTop, size.width + origin.x,
							size.height - origin.y - spaceY * i
									+ graphMarginTop, paint);
				}

				paint.setTextAlign(Align.RIGHT);
				paint.setAlpha(255);
				paint.setAntiAlias(true);
				canvas.drawText(
						String.format(
								"%.1f",
								minY
										+ ((i * spaceY - axisY
												.getAutoscaleMargin()) / scaleY)),
						origin.x - 15, size.height - origin.y - i * spaceY + 4
								+ graphMarginTop, paint);
				paint.setAntiAlias(false);
				continue;
			}

			canvas.drawLine(origin.x, size.height - origin.y - spaceY * i
					+ graphMarginTop, origin.x + -5, size.height - origin.y
					- spaceY * i + graphMarginTop, paint);
			if (Grid == true) {
				// 그리드를 그린다.
				paint.setAlpha(30);
				canvas.drawLine(origin.x, size.height - origin.y - spaceY * i
						+ graphMarginTop, size.width + origin.x, size.height
						- origin.y - spaceY * i + graphMarginTop, paint);
			}
		}
	}

	/**
	 * @param title
	 *            X축의 이름
	 * @param canvas
	 *            Canvas
	 * @param paint
	 *            Paint
	 */
	@SuppressWarnings("unused")
	private void makeLabelX(String title, Canvas canvas) {
		String labelX = title;
		Paint paint = new Paint();

		paint.setAntiAlias(true);
		paint.setTextAlign(Align.CENTER);
		paint.setTextSize(18);
		paint.setColor(Color.rgb(14, 132, 204));

		canvas.drawText(labelX, (size.width + origin.x) / 2, size.height
				- origin.y + 50 + graphMarginTop, paint);
	}

	/**
	 * @param title
	 *            Y축의 이름
	 * @param canvas
	 *            Canvas
	 * @param paint
	 *            Paint
	 */
	@SuppressWarnings("unused")
	private void makeLabelY(String title, Canvas canvas) {
		String labelY = title;
		Paint paint = new Paint();

		paint.setAntiAlias(true);
		paint.setTextAlign(Align.CENTER);
		paint.setTextSize(18);
		paint.setColor(Color.rgb(14, 132, 204));

		canvas.translate(origin.x - 50, (size.height - origin.y) / 2
				+ graphMarginTop);
		canvas.rotate(-90);
		canvas.drawText(labelY, 0, 0, paint);
		canvas.restore();
	}

	public void setColorLine(int color) {
		colorLine = color;
	}

	public void setColorPoint(int color) {
		colorPoint = color;
	}
}
